from abc import ABC, abstractmethod
from typing import Optional, Any

from fastapi import UploadFile
import asyncio
from blurhash import encode
from PIL import Image
import numpy as np
from io import BytesIO


class BaseStorage(ABC):
    @abstractmethod
    async def generate_file_info(self, file: UploadFile) -> dict[str, Any]:
        pass

    @staticmethod
    async def _generate_image_hash(fp) -> Optional[str]:
        content = None
        if isinstance(fp, str):
            content = fp
        if isinstance(fp, bytes):
            content = BytesIO(fp)
        if isinstance(fp, UploadFile):
            content = BytesIO(fp.file.read())

        def _generate():
            try:
                with Image.open(content) as img:
                    img.thumbnail((128, 128))
                    img = img.convert("RGB")
                    img_array = np.array(img, dtype=np.float64)
                    return encode(img_array, components_x=4, components_y=3)
            except Exception:
                return None

        return await asyncio.to_thread(_generate)
